package ext.acae2.dms.load;

import java.beans.PropertyVetoException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import wt.content.ApplicationData;
import wt.content.ContentRoleType;
import wt.content.ContentServerHelper;
import wt.epm.EPMApplicationType;
import wt.epm.EPMAuthoringAppType;
import wt.epm.EPMDocument;
import wt.epm.EPMDocumentMaster;
import wt.epm.EPMDocumentType;
import wt.fc.PersistenceHelper;
import wt.fc.collections.WTValuedHashMap;
import wt.folder.Folder;
import wt.folder.FolderHelper;
import wt.inf.container.WTContainer;
import wt.inf.container.WTContainerRef;
import wt.log4j.LogR;
import wt.util.WTException;
import wt.util.WTMessage;
import wt.util.WTPropertyVetoException;

import com.ptc.core.foundation.type.server.impl.TypeHelper;
import com.ptc.core.meta.common.TypeIdentifier;

import ext.acae2.dms.bean.DataBean;
import ext.acae2.dms.bean.EPMDocumentBean;
import ext.acae2.dms.resource.DataExchangeResource;
import ext.acae2.util.IBAUtil;
import ext.acae2.util.QueryUtil;
import ext.acae2.util.StringUtil;
import ext.acae2.util.VersionUtil;

/**
 * EPMDocumentFacotry for create EPMDocument from a bean class.
 * 
 * @author
 *
 */
public class EPMDocumentFactory {

    private static final Logger LOGGER = LogR.getLogger(EPMDocumentFactory.class.getName());
    private static final String RESOURCE = DataExchangeResource.class.getName();
    private static EPMDocumentFactory factory = null;
    
    private static final HashMap<String, EPMDocumentType> docTypesMap = new HashMap<String, EPMDocumentType>();
    
    private EPMDocumentFactory() {}
    
    /**
     * Singleton Pattern to get factory
     * 
     * @return factory
     */
    public static synchronized EPMDocumentFactory getInstance() {
        if (factory == null) {
            factory = new EPMDocumentFactory();
        }
        return factory;
    }
    
    // static initialization
    static {
        // docTypes - always index in lower case
        docTypesMap.put("UGMASTER", EPMDocumentType.toEPMDocumentType ("CADCOMPONENT"));
        docTypesMap.put("UGPART", EPMDocumentType.toEPMDocumentType ("CADDRAWING"));
        docTypesMap.put("AutoCAD", EPMDocumentType.toEPMDocumentType ("CADDRAWING"));
        docTypesMap.put("ACAD", EPMDocumentType.toEPMDocumentType ("CADDRAWING"));
        docTypesMap.put("ASSEMBLY", EPMDocumentType.toEPMDocumentType ("CADASSEMBLY"));  //add by cnie
//        docTypesMap.put("mfg", EPMDocumentType.toEPMDocumentType ("MANUFACTURING"));
//        docTypesMap.put("sec", EPMDocumentType.toEPMDocumentType ("SKETCH"));
//        docTypesMap.put("frm", EPMDocumentType.toEPMDocumentType ("FORMAT"));
//        docTypesMap.put("rep", EPMDocumentType.toEPMDocumentType ("REPORT"));
//        docTypesMap.put("dgm", EPMDocumentType.toEPMDocumentType ("DIAGRAM"));
//        docTypesMap.put("lay", EPMDocumentType.toEPMDocumentType ("LAYOUT"));
//        docTypesMap.put("mrk", EPMDocumentType.toEPMDocumentType ("MARKUP"));
//        docTypesMap.put("gph", EPMDocumentType.toEPMDocumentType ("UDF")); 

    }
    
    /**
     * Main method to create EPMDocument from a bean class.
     * 
     * @param bean class to store info 
     * @return
     * @throws WTException
     * @throws IOException 
     * @throws PropertyVetoException 
     * @throws FileNotFoundException 
     */
    public EPMDocument createDocument(DataBean bean) throws WTException, FileNotFoundException, PropertyVetoException, IOException {
        LOGGER.debug("> Start createDocument");
        LOGGER.debug("bean class: " + bean.getClass().getName());
        
        if (bean instanceof EPMDocumentBean) {
            return createEPMDocument(bean);
        }
        
        LOGGER.debug("> End createDocument");
        return null;
    }
    
    
    /**
     * Main method to create EPMDocument from a bean class.
     * 
     * @param bean
     * @return
     * @throws WTException
     * @throws IOException 
     * @throws PropertyVetoException 
     * @throws FileNotFoundException 
     */
    private EPMDocument createEPMDocument(DataBean bean) throws WTException, FileNotFoundException, PropertyVetoException, IOException {
        LOGGER.debug("> Start createEPMDocument");
        
        EPMDocumentBean epmDocumentBean = (EPMDocumentBean) bean;
        
        String number = epmDocumentBean.getNumber();
        
        Set<String> keys = epmDocumentBean.getMap().keySet();
        String drawingNo = "";
        for(String key:keys){
        	if(key!=null&&key.indexOf("drawingNo")>-1){
        		drawingNo = epmDocumentBean.getMap().get(key);
        		break;
        	}
        }
        
        String folderName = null;
        
        if(drawingNo.length()>4&&StringUtil.isNum(drawingNo.substring(0, 4))){
        	folderName = "/Default/" + WTMessage.getLocalizedMessage(RESOURCE, DataExchangeResource.EPMDOCUMENT_FOLDER_NAME) 
                    + "/" + drawingNo.substring(0, 4);
        }else{
        	folderName = "/Default/" + WTMessage.getLocalizedMessage(RESOURCE, DataExchangeResource.EPMDOCUMENT_FOLDER_NAME) 
                    + "/" + "未分类";
        }
        
        //change productName   ******************************************************************
        EPMDocument document = createCommonEPMDocumentToFolder(
                "WCTYPE|wt.epm.EPMDocument|com.acae.DefaultEPMDocument", epmDocumentBean.getType(), epmDocumentBean.getName(), epmDocumentBean.getNumber(), "CJ-1000AX", folderName,bean.getVersion());

        //add PrimaryContent
        String filePath = epmDocumentBean.getLocationRef();
        ApplicationData applicationdata = ApplicationData.newApplicationData(document);
        applicationdata.setRole(ContentRoleType.toContentRoleType("PRIMARY"));
        LOGGER.debug("Upload EPMPrimaryContent:" + filePath);
        if (!"".equals(filePath)) {
            ContentServerHelper.service.updateContent(document, applicationdata, filePath);
        }
        
        
        //add iba
//    	private String PARTTYPE;
//    	private String BLANKSPEC;
//    	private String BLANKSTATE;
//    	private String CHARACTERTYPE;
//    	private String DRAWINGNO;
//    	private String MASS;
//    	private String MATERIAL;
//    	private String MATERIALSTANDARD;
//    	private String OBJNAME;
//    	private String UNITE;
        
        IBAUtil iba = new IBAUtil(document);
        
        Set<String> key = epmDocumentBean.getMap().keySet();    
		 for (Iterator<String> it = key.iterator(); it.hasNext();) {            
			 String s = (String) it.next(); 
			 try{
				 iba.setIBAValue(s, epmDocumentBean.getMap().get(s));
			 }catch(Exception e){
				 iba.setIBAValue("remark", epmDocumentBean.getREMARK()+s+"="+epmDocumentBean.getMap().get(s)+",");
			 }
		 }
        
//        iba.setIBAValue("characterType", epmDocumentBean.getCHARACTERTYPE());
//        iba.setIBAValue("mass", epmDocumentBean.getMASS());
//        iba.setIBAValue("unite", epmDocumentBean.getUNITE());
//        iba.setIBAValue("material", epmDocumentBean.getMATERIAL());
//        iba.setIBAValue("materialStandard", epmDocumentBean.getMATERIALSTANDARD());
//        iba.setIBAValue("blankSpec", epmDocumentBean.getBLANKSPEC());
//        iba.setIBAValue("blankState", epmDocumentBean.getBLANKSTATE());
//        iba.setIBAValue("parttype", epmDocumentBean.getPARTTYPE());
//        iba.setIBAValue("objName", epmDocumentBean.getOBJNAME());
//        iba.setIBAValue("drawingNo", epmDocumentBean.getDRAWINGNO());
//        iba.setIBAValue("copyright", epmDocumentBean.getCOPYRIGHT());
//        iba.setIBAValue("model", epmDocumentBean.getMODEL());
//        iba.setIBAValue("design", epmDocumentBean.getDESIGN());
//        iba.setIBAValue("secretLevel", epmDocumentBean.getSECRETLEVEL());
//        iba.setIBAValue("securityDeadline", epmDocumentBean.getSECURITYDEADLINE());
        iba.saveIBAHolder(document);
        
        LOGGER.debug("> End createEPMDocument");
        return document;
    }
    
    /**
     * Main method to create a common EPMDocument according to type, name, number and product name.
     * 
     * @param type
     * @param name
     * @param number
     * @return
     * @throws WTException
     * @throws WTPropertyVetoException
     */
    public EPMDocument createCommonEPMDocument(String type, String docType, String name, String number, String productName) throws WTException, WTPropertyVetoException {
        LOGGER.debug("> Start createCommonEPMDocument");
        LOGGER.debug("type: " + type);
        LOGGER.debug("docType: " + docType);
        LOGGER.debug("name: " + name);
        LOGGER.debug("number: " + number);

        /*
         * Create the EPMDocuments
         */
        EPMDocument doc = null;

        TypeIdentifier typeidentifier = TypeHelper.getTypeIdentifier(type);
        doc = (EPMDocument) TypeHelper.newInstance(typeidentifier);
        
        doc.setName(name);
        doc.setCADName(name);
        doc.setContainer(QueryUtil.getContainerByName(productName));
        doc.setNumber(number);
        EPMDocumentType epmDocType = (EPMDocumentType) docTypesMap.get(docType);
        
        doc.setDocType(epmDocType);
        
        EPMDocumentMaster master = (EPMDocumentMaster) doc.getMaster();
        
        //set value: ug
        EPMAuthoringAppType epmauthoringapptype = EPMAuthoringAppType.toEPMAuthoringAppType("UG");
        master.setAuthoringApplication(epmauthoringapptype);
        master.setOwnerApplication(EPMApplicationType.toEPMApplicationType("EPM"));
        doc.setMaster(master);
        
        doc = (EPMDocument) PersistenceHelper.manager.save(doc);
        
        LOGGER.debug("> End createCommonEPMDocument");
        return doc;
    }
    
    public EPMDocument createCommonEPMDocumentToFolder(String type, String docType, String name, String number, String productName, String folderName,String version) throws WTException, WTPropertyVetoException {
        LOGGER.debug("> Start createCommonEPMDocumentToFolder");
        LOGGER.debug("type: " + type);
        LOGGER.debug("docType: " + docType);
        LOGGER.debug("name: " + name);
        LOGGER.debug("number: " + number);

        /*
         * Create the EPMDocuments
         */
        EPMDocument doc = null;

        TypeIdentifier typeidentifier = TypeHelper.getTypeIdentifier(type);
        doc = (EPMDocument) TypeHelper.newInstance(typeidentifier);
        
        WTContainer product = QueryUtil.getContainerByName(productName);
        
        doc.setName(name);
        doc.setCADName(name);  //add by cnie 
        doc.setContainer(product);
        doc.setNumber(number);
        EPMDocumentType epmDocType = (EPMDocumentType) docTypesMap.get(docType);
        doc.setDocType(epmDocType);
        
        EPMDocumentMaster master = (EPMDocumentMaster) doc.getMaster();
        EPMAuthoringAppType epmauthoringapptype = null;
        if("UGMASTER".equals(docType) || "UGPART".equals(docType)||"ASSEMBLY".equals(docType)){  //add by cnie "ASSEMBLY".equals(docType)
        	//set value: ug
        	epmauthoringapptype = EPMAuthoringAppType.toEPMAuthoringAppType("UG");
        }else if("AutoCAD".equals(docType) || "ACAD".equals(docType) ){
        	//set value: autocad
        	epmauthoringapptype = EPMAuthoringAppType.toEPMAuthoringAppType("ACAD");
        }
        master.setAuthoringApplication(epmauthoringapptype);
        master.setOwnerApplication(EPMApplicationType.toEPMApplicationType("EPM"));
        doc.setMaster(master);
        
        
        //set to folder
		Folder folder = null;
		try {
			folder = QueryUtil.getFolder(folderName, WTContainerRef.newWTContainerRef(product));
		} catch (Exception e) {
			folder = null;
		}

		if (folder != null) {
			WTValuedHashMap map = new WTValuedHashMap();
			map.put(doc, folder);
			FolderHelper.assignLocations(map);
		} else {
			folder = FolderHelper.service.saveFolderPath(folderName, WTContainerRef.newWTContainerRef(product));
			WTValuedHashMap map = new WTValuedHashMap();
			map.put(doc, folder);
			FolderHelper.assignLocations(map);
		}
		
		if (StringUtils.isNotBlank(version)) {
			String[] versionArr = version.split("\\.");
			if (versionArr.length == 2) {
				VersionUtil.setVersion(doc, versionArr[0]);
				VersionUtil.setIteration(doc, versionArr[1]);
			} else {
				VersionUtil.setVersion(doc, versionArr[0]);
			}
		}
        
        doc = (EPMDocument) PersistenceHelper.manager.save(doc);
        
        LOGGER.debug("> End createCommonEPMDocumentToFolder");
        return doc;
    }
    
    
}
